package com.daji.concurrency.multithread_future_callback;


import java.util.concurrent.*;

/*
    使用future。为什么要用线程池(ExecutorService) ？ 因为ExecutorService可以返回Future对象
    如果别的启动线程的方式也可以获取一个Future对象，也可以用别的。
    目前多是ExecutorService与Future连用。如果有别的再补充
*/
public class E01_Future {
    public static void main(String[] args) {
        //线程池,初始化该线程池里面有4个线程。
        ExecutorService executor = Executors.newFixedThreadPool(4);

        for (int i = 0; i < 4; i++) {
            // 定义任务:
            Callable<String> task = new Task();
            // 这一步是在线程池中启动线程： 提交任务并获得Future:
            Future<String> future = executor.submit(task);  //执行该线程会获得一个future
            // 从Future获取异步执行返回的结果:
            try {
                //TODO 由此可知，这个future.get() 是阻塞式的。如果想要非阻塞，见CompletableFuture章节
                String result = future.get(); // 阻塞主线程直到任务返回结果。该方法会抛两个异常。
                System.out.println(result);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();

            }
        }

        executor.shutdown();    //关闭线程池
        System.out.println("线程池已关闭");

    }
}


//开线程可以实现Runnable，也可以实现Callable
//Callable有个好处，就是这个线程执行完毕之后有返回值
class Task implements Callable<String> {//Callable接口是一个泛型接口，可以返回指定类型的结果。这里我们指定为String

    //String为返回值
    @Override
    public String call() throws Exception {
        System.out.println("发送成功");
        Thread.sleep(10000);
        return "刚刚睡了10秒钟，执行了一个长任务!";
    }

}